/*
 * Copyright (c) 2010, Jim Hollinger
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Jim Hollinger nor the names of its contributors
 *     may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <io.h>
#include <conio.h>
#include <string>

#include "debughelper/debughelper.h"
#include "datachannel/datachannelfactory.h"
#include "logger/logger.h"
#include "properties/properties.h"
#include "nmeainterface.h"
#include "nmeaopenjauscomponent.h"


const char *NMEAJGP_VERSION = "V1.0";

void usage() {
    printf("Usage: NMEAJGP [config_filename]\n");
    exit(0);
}

int main(int argc, char *argv[]) {
#ifdef _DEBUG
    // turn on memoery leak detection
    // in a watch window, set the global variable
    // {,,msvcr90d.dll}_crtBreakAlloc
    // to break on offending memory block allocation
    int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
    _CrtSetDbgFlag(tmpDbgFlag);
#endif

    // default config values
    std::string prop_filename    = "nmeajgpConfig.txt";
    std::string descriptor       = "file://wpsnmea.txt:read:text";
    double      componentRate_hz = 10.0;

    // check command line arguments
    if (argc >= 3) {
        usage();
    } else if (argc >= 2) {
        if ((argv[1][0] == '?') || (argv[1][1] == '?')) {
            usage();
        }
        prop_filename = argv[1];
    }

    // initialize logger
    logger::Logger::initialize("main");
    logger::Logger *logger = logger::Logger::getInstance();
    if (logger == NULL) {
        fprintf(stderr, "Failed to create logger, exiting ...\n");
        exit(0);
    }
    logger->info("NMEA JAUS Global Pose sensor %s", NMEAJGP_VERSION);

    // load properties file
    prop::Properties properties;
    bool prop_flag = properties.load(prop_filename);
    if (prop_flag) {
        logger->info("Loaded properties file \"%s\"", prop_filename.c_str());
        descriptor = properties.getProperty(
            "descriptor", descriptor);
        componentRate_hz  = properties.getFloatProperty(
            "componentRate_hz", componentRate_hz);
        properties.listUnrecognized(stderr, "Unrecognized properties:\n");
    } else {
        logger->error("Failed to open properties file \"%s\"",
            prop_filename.c_str());
        if (properties.list(prop_filename,
            "# NMEA JAUS Global Pose sensor config file\n")) {
            logger->info("Created properties file \"%s\" with default values",
                prop_filename.c_str());
        }
    }

    // create nmea interface
    nmeajgp::NmeaInterface *nmeaInterface = new nmeajgp::NmeaInterface(logger);
    if (nmeaInterface->init(descriptor)) {
        nmeaInterface->start();

        // create nmea open jaus component
        nmeajgp::NmeaOpenJausComponent *nmeaComponent =
            new nmeajgp::NmeaOpenJausComponent(nmeaInterface, logger);
        if (nmeaComponent->init(componentRate_hz)) {
            nmeaComponent->start();

            // wait for user to stop
            int c = 0;
            do {
                c = _getch();
            } while (c != 0x1B);

            // stop nmea open jaus component
            nmeaComponent->stop();
        }
        delete nmeaComponent;
        nmeaComponent = NULL;

        // stop nmea interface
        nmeaInterface->stop();
    }
    delete nmeaInterface;
    nmeaInterface = NULL;

    // cleanup logger
    logger::Logger::cleanup();

    // exit app
    return 0;
}
